package org.wutopia.labcloud.domain.file.service.dubbo.impl;

import io.minio.*;
import io.minio.errors.*;
import io.minio.http.Method;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Service;
import org.wutopia.labcloud.service.api.service.dubbo.FileService;
import org.wutopia.labcloud.service.api.service.dubbo.dto.input.UploadUrlInputDTO;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;
import java.util.concurrent.TimeUnit;


@DubboService
@Service
@AllArgsConstructor
@Slf4j
public class FileServiceImpl implements FileService {

    private MinioClient minioClient;

    @Override
    public String getUploadUrl(UploadUrlInputDTO dto) {

        String uploadUrl = null;


        try {
            uploadUrl = minioClient.getPresignedObjectUrl(
                    GetPresignedObjectUrlArgs.builder()
                            .method(Method.PUT) // 指定为 PUT 方法
                            .bucket(dto.getBucket())
                            .object(dto.getObjectName())
                            .expiry(1, TimeUnit.HOURS)
                            .build()
                );
        } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException |
                 InvalidResponseException | IOException | NoSuchAlgorithmException | XmlParserException |
                 ServerException e) {
            return null;
        }


        return uploadUrl;
    }

    @Override
    public String uploadFile(String bucketName, String imageUrl) {


        try {

            // 1. 下载网络图片
            URL url = new URL(imageUrl);
            byte[] imageBytes;
            InputStream in = url.openStream();
            imageBytes = in.readAllBytes();
            in.close();

            in = url.openStream();

            // 2. 生成唯一文件名 & 获取图片类型
            String fileExtension = imageUrl.substring(imageUrl.lastIndexOf(".") + 1);
            String fileName = UUID.randomUUID() + "." + fileExtension; // e.g. "a1b2c3d4.jpg"
            String contentType = "image/" + fileExtension; // e.g. "image/jpeg"

            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(bucketName)
                            .object(fileName)
                            .stream(in, imageBytes.length, -1) // 长度必须明确
                            .contentType(contentType)
                            .build()
            );
            return fileName;
        } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException |
                 InvalidResponseException | IOException | NoSuchAlgorithmException | ServerException |
                 XmlParserException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String getFileUrl(String bucketName, String objectName) {
        try {

            // 检查对象是否存在
            StatObjectResponse statObjectResponse = minioClient.statObject(
                    StatObjectArgs.builder()
                            .bucket(bucketName)
                            .object(objectName)
                            .build()
            );
            if (statObjectResponse == null) {
                return null;
            }

            return minioClient.getPresignedObjectUrl(
                    GetPresignedObjectUrlArgs.builder()
                            .method(Method.GET)
                            .bucket(bucketName)
                            .object(objectName)
                            .expiry(1, TimeUnit.HOURS) // 1小时有效期
                            .build());
        } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException |
                 InvalidResponseException | IOException | NoSuchAlgorithmException | XmlParserException |
                 ServerException e) {
            log.error("获取文件下载链接失败: ", e);
            return null;
        }
    }
}
